//
//  BaseServices.swift
//  IDF
//
//  Created by 陈徐挺 on 23/03/2018.
//  Copyright © 2018 Jesse.chen. All rights reserved.
//

import UIKit
import Alamofire
import PromiseKit
import SwiftyJSON
import SVProgressHUD
import AliyunOSSiOS
import YYCache


#if DEBUG
    let kRootServerURL = "http://test.smalldebit.club/api/"
    let aliyunBucket = "debit"
    let aliyunEndpoint = "oss-cn-hongkong.aliyuncs"
    let aliyunToken = "http://test.h5.smalldebit.club/aliyun/getStsToken"
    let jAppKey = "009613bc5c3f67a9e593ce71"
#else
    let kRootServerURL = "http://test.smalldebit.club/api/"
    let aliyunBucket = "debit"
    let aliyunEndpoint = "oss-cn-hongkong.aliyuncs"
    let aliyunToken = "http://test.h5.smalldebit.club/aliyun/getStsToken"
    let jAppKey = "009613bc5c3f67a9e593ce71"
#endif

func initAliyun() {
    let request = RequestData(path: "Main/GetSTSToken")
    let _ = netRequest(request).then { json -> Void in
        let endpoint = "https://\(aliyunEndpoint).com"
        let credential = OSSStsTokenCredentialProvider(accessKeyId: json["AccessKeyId"].stringValue, secretKeyId: json["AccessKeySecret"].stringValue, securityToken: json["Security"].stringValue)
        client = OSSClient(endpoint: endpoint, credentialProvider: credential)
    }
}

func getUserDebitAttention() {
    let _ = Record.getUserDebitAttention().then { obj -> Void in
        if let debitId = obj.debitId, debitId != 0 {
            let debitAttentionView = DebitAttentionView(frame: appWindow.bounds)
            debitAttentionView.record = obj
            debitAttentionView.setView()
            appWindow.addSubview(debitAttentionView)
        }
    }
}

func syncUserRegistration(_ registrationId: String) {
    let dic = ["registrationId": registrationId]
    let request = RequestData(path: "User/SyncUserRegistration", param: dic)
    let _ = netRequest(request)
}

func showLoginView() {
    let loginView = LoginView(frame: appWindow.bounds)
    appWindow.addSubview(loginView)
}



public struct RequestData {
    var url: String!
    var method: HTTPMethod!
    var param: Parameters!
    var paramArr: [[String: Any]]!
    var headers: HTTPHeaders!
    var encoding: ParameterEncoding!
    
    init(host: String = kRootServerURL, path: String = "", method: HTTPMethod = .get, param: Parameters = [:], paramArr: [[String: Any]] = [],headers: HTTPHeaders = ["Content-Type": "application/json"], encoding: ParameterEncoding = URLEncoding.default ) {
        self.url = host + path
        self.method = method
        self.param = param
        self.paramArr = paramArr
        self.headers = headers
        self.encoding = encoding
    }

}

func jsonToData(jsonDic: [String: Any]) -> Data? {
    if(!JSONSerialization.isValidJSONObject(jsonDic)) {
        dPrint("is not a valid json object")
        return nil
    }
    let data = try? JSONSerialization.data(withJSONObject: jsonDic, options: [])
    let str = String(data: data!, encoding: String.Encoding.utf8)
    dPrint("Json Str:\(str!)")
    return data
}




func netRequest(_ req: RequestData, dataFn: ((_ json: JSON) -> Void)? = nil) -> Promise<JSON> {
    let (wrappingPromise, fulfill, reject) = Promise<JSON>.pending()
    var alamofire: Promise<Data>
    if req.paramArr.count > 0 {
        var request = URLRequest(url: URL(string: req.url)!)
        request.httpMethod = req.method.rawValue
        request.setValue("iOS", forHTTPHeaderField: "qudao")
        request.setValue("1", forHTTPHeaderField: "version")
        request.setValue("1", forHTTPHeaderField: "deviceNo")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.timeoutInterval = 11// 11 secs timeout
        if appUser != nil, let token = appUser.token, let userId = appUser.userId {
            request.setValue(token, forHTTPHeaderField: "token")
            request.setValue("\(userId)", forHTTPHeaderField: "userId")
        }
        request.httpBody = try! JSONSerialization.data(withJSONObject: req.paramArr)
        alamofire = Alamofire.request(request).responseData()
        } else {
        var request = req
        request.headers["qudao"] = "iOS"
        request.headers["version"] = "1"
        request.headers["deviceNo"] = "1"
        if appUser != nil, let token = appUser.token, let userId = appUser.userId {
            request.headers["token"] = token
            request.headers["userId"] = "\(userId)"
            request.param["userId"] = "\(userId)"
        }
        alamofire = Alamofire.request(request.url, method: request.method, parameters: request.param, encoding: request.encoding ,headers: request.headers).responseData()
    }
    alamofire.then {
        data -> Void in
        do {
            let json = try JSON(data: data)
            let result = json["result"].intValue
            if result == 0 {
                let data: JSON = json["data"]
                if let fn = dataFn {
                    fn(data)
                }
                fulfill(data)
                SVProgressHUD.dismiss()
            } else {
                let msg = json["message"].stringValue
                SVProgressHUD.showError(withStatus: msg)
                SVProgressHUD.dismiss(withDelay: 3)
                reject(NSError(domain: json["message"].stringValue, code: json["errorCode"].intValue, userInfo: nil))
                // Token 过期退出登录
                if result == -100015 {
                    appUser = User()
                    let cache = YYCache(name: "appcache")
                    cache?.removeAllObjects()
                    appLogined = false
                    mainTabBarController.selectedIndex = 0
                    nowNavgationController = mainTabBarController.viewControllers![0] as! UINavigationController
                    showLoginView()
                }
            }
        } catch {
            SVProgressHUD.showError(withStatus: "network error")
            SVProgressHUD.dismiss(withDelay: 1.5)
            reject(error)
        }
    }
        .catch { error in
            SVProgressHUD.showError(withStatus: "network error")
            SVProgressHUD.dismiss(withDelay: 1.5)
            reject(error)
    }
    return wrappingPromise
}





